package com.buli.util;

import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.errors.MinioException;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.validation.annotation.Validated;

import javax.annotation.PostConstruct;
import javax.validation.constraints.NotBlank;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

@Configuration
@ConfigurationProperties(prefix = "spring.application.minio")
@Validated
@Data
public class MinioConfig {

    private static final Logger logger = LoggerFactory.getLogger(MinioConfig.class);

    @NotBlank
    private String endpoint;

    @NotBlank
    private String accessKey;

    @NotBlank
    private String secretKey;

    @NotBlank
    private String bucketName;

    private MinioClient minioClient;

    @PostConstruct
    public void init() {
        minioClient = initializeMinioClient();
        ensureBucketExists();
    }

    private MinioClient initializeMinioClient() {
        int retryCount = 3;
        for (int i = 0; i < retryCount; i++) {
            try {
                return MinioClient.builder()
                        .endpoint(endpoint)
                        .credentials(accessKey, secretKey)
                        .build();
            } catch (Exception e) {
                logger.error("Attempt {} to initialize MinioClient failed: {}", i + 1, e.getMessage());
                if (i < retryCount - 1) {
                    try {
                        Thread.sleep(2000); // 等待2秒后重试
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        logger.error("Thread interrupted during retry wait: {}", ie.getMessage());
                    }
                }
            }
        }
        logger.error("Failed to initialize MinioClient after {} retries.", retryCount);
        throw new RuntimeException("Failed to initialize MinioClient");
    }

    private void ensureBucketExists() {
        try {
            boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!isExist) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
                logger.info("Bucket {} created successfully.", bucketName);
            } else {
                logger.info("Bucket {} already exists.", bucketName);
            }
        } catch (MinioException | IOException | NoSuchAlgorithmException | InvalidKeyException e) {
            logger.error("Error occurred while checking or creating bucket: {}", e.getMessage());
            throw new RuntimeException("Error occurred while checking or creating bucket", e);
        }
    }

    @Bean
    @Lazy
    public MinioClient minioClient() {
        return minioClient;
    }

    @Bean
    public String minioBucket() {
        return bucketName;
    }


}
